package com.yejiali.backend.service.impl;

import cn.hutool.core.bean.BeanUtil;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.yejiali.backend.common.constant.SystemConstant;
import com.yejiali.backend.entity.Users;
import com.yejiali.backend.entity.VideoLikes;
import com.yejiali.backend.entity.Videos;
import com.yejiali.backend.entity.vo.VideoLikeVO;
import com.yejiali.backend.mapper.UsersMapper;
import com.yejiali.backend.mapper.VideoLikesMapper;
import com.yejiali.backend.mapper.VideosMapper;
import com.yejiali.backend.response.Response;
import com.yejiali.backend.service.VideoLikesService;
import com.yejiali.backend.util.MessageUtil;
import com.yejiali.backend.util.RedisUtil;
import com.yejiali.backend.ws.WebSocketServer;
import jakarta.websocket.Session;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.*;
import java.util.concurrent.ConcurrentHashMap;

/**
 * 视频点赞表(VideoLikes)表服务实现类
 *
 * @author yejiali
 * @since 2025-08-15 09:25:28
 */
@Service
public class VideoLikesServiceImpl extends ServiceImpl<VideoLikesMapper, VideoLikes> implements VideoLikesService {

    @Autowired
    private UsersMapper usersMapper;
    @Autowired
    private VideosMapper videosMapper;

    @Autowired
    private RedisUtil redisUtil;

    /**
     * 点赞视频
     * @param userId
     * @param videoId
     * 设计思路
     * 1.SET缓存点赞用户列表 key为video:likeUser videoId, value为点赞用户id;
     * 2.String缓存点赞数量 key为video:likeCount videoId, value为点赞数量;
     * 点赞流程
     * 1.先redis中SET缓存点赞用户列表,查看是否有用户的点赞记录
     * 2.若有用户的点赞记录,则返回已点赞
     * 3.若没有记录就去数据库中查看是否有记录，没有记录就插入一条
     * 4.并同步到redis中
     * 4.给原视频博主发送被赞通知
     * 5.返回点赞状态
     * @return
     */
    @Override
    public Response<String> likeVideo(Long userId, Long videoId) throws JsonProcessingException {
        //查询视频是否存在
        Videos videos = videosMapper.selectById(videoId);
        if (videos == null) {
            return Response.error(400, "视频不存在");
        }
        //查看redis中是否有记录,增加点赞数
        String likeUserKey = "video:likeUser:" + videoId;
        //若redis中已有记录，则说明已点赞了
        if(redisUtil.sHasKey(likeUserKey,userId)){
            return Response.error(400, "用户已点赞");
        }
        //redis中无记录就去查数据库
        QueryWrapper<VideoLikes> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("user_id",userId);
        queryWrapper.eq("video_id",videoId);
        //有记录
        if(getOne(queryWrapper)!=null){
            //同步到redis中
            redisUtil.sSet(likeUserKey,userId);
            return Response.error(400, "用户已点赞");
        }
        //无记录,在数据库中插记录
        VideoLikes videoLikes = VideoLikes.builder()
                .userId(userId)
                .videoId(videoId)
                .accepterId(videos.getUploaderId())
                .likeStatus(1)
                .build();
        this.save(videoLikes);
        //同步到redis中
        redisUtil.sSet(likeUserKey,userId);
        redisUtil.incr("video:likeCount:"+videoId,1L);
        //给视频博主发送通知
        //发送消息
        String message = MessageUtil.getMessage(SystemConstant.SEND_LIKE_MESSAGE, videos.getUploaderId().toString(), "你的视频被点赞啦");
        ConcurrentHashMap<String, WebSocketServer> webSocketMap = WebSocketServer.getWebSocketMap();
        WebSocketServer webSocketServer = webSocketMap.get(videos.getUploaderId().toString());
        //是否在线
        if(webSocketServer!=null){
            try {
                Session session = webSocketServer.getSession();
                if(session!=null){
                    session.getBasicRemote().sendText(message);
                }
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
        //不管是否在线都先存储未读数
        redisUtil.hincr("user:unread:"+videos.getUploaderId(),"likeMessage",1);
        return Response.success("点赞成功");
    }

    /**
     * 取消点赞视频
     * @param userId
     * @param videoId
     * @return
     */
    @Override
    public Response<String> unlikeVideo(Long userId, Long videoId) {
        //查询视频是否存在
        Videos videos = videosMapper.selectById(videoId);
        if (videos == null) {
            return Response.error(400, "视频不存在");
        }
        //查看redis中是否有记录
        String likeUserKey = "video:likeUser:" + videoId;
        boolean hasLiked = redisUtil.sHasKey(likeUserKey, userId);
        if(hasLiked){
            redisUtil.setRemove(likeUserKey,userId);
            redisUtil.decr("video:likeCount:"+videoId,1L);
        }
        //删除数据库中记录
        QueryWrapper<VideoLikes> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("user_id",userId);
        queryWrapper.eq("video_id",videoId);
        VideoLikes videoLikes = this.getOne(queryWrapper);
        if(videoLikes == null){
            return Response.error(400, "用户未点赞");
        }
        this.remove(queryWrapper);
        return Response.success("取消点赞成功");
    }

    /**
     * 查询用户收到的视频点赞通知
     * @param userId
     * @return
     */
    @Override
    public Response<List<VideoLikeVO>> receiveLikeVideo(Long userId) {
        //查询用户是否存在
        Users user = usersMapper.selectById(userId);
        if (user == null) {
            return Response.error(400, "用户不存在");
        }
        QueryWrapper<VideoLikes> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("accepter_id",userId);
        queryWrapper.eq("is_deleted",0);
        queryWrapper.orderByDesc("created_at");
        List<VideoLikes> videoLikes = this.list(queryWrapper);
        if(videoLikes.isEmpty()){
            return Response.success(new ArrayList<>());
        }
        List<VideoLikeVO> videoLikeVOList = BeanUtil.copyToList(videoLikes, VideoLikeVO.class);
        Set<Long> userIds = new HashSet<>();
        List<Long> videoIds = new ArrayList<>();
        //提取用户id和视频id
        videoLikeVOList.forEach(videoLikeVO -> {
            userIds.add(videoLikeVO.getUserId());
            videoIds.add(videoLikeVO.getVideoId());
        });
        //批量查询
        Map<Long,Users> userMap=new HashMap<>();
        Map<Long,String> videoMap=new HashMap<>();
        //查询用户信息
        List<Users> users = usersMapper.selectBatchIds(userIds);
        for(Users user1:users){
            userMap.put(user1.getUserId(),user1);
        }
        //查询视频信息
        List<Videos> videos = videosMapper.selectBatchIds(videoIds);
        for(Videos video:videos){
            videoMap.put(video.getVideoId(),video.getPictureUrl());
        }
        //填充用户信息和视频信息
        videoLikeVOList.forEach(videoLikeVO -> {
            videoLikeVO.setNickname(userMap.get(videoLikeVO.getUserId()).getNickname());
            videoLikeVO.setAvatar(userMap.get(videoLikeVO.getUserId()).getAvatar());
            videoLikeVO.setPictureUrl(videoMap.get(videoLikeVO.getVideoId()));
        });
        return Response.success(videoLikeVOList);
    }

    /**
     * 逻辑删除收到的视频点赞通知
     * @param videoId
     * @return
     */
    @Override
    public Response<String> deleteLikeVideo(Long videoId) {
        VideoLikes videoLikes = this.getById(videoId);
        if(videoLikes == null|| videoLikes.getIsDeleted() == 1){
            return Response.error(400,"视频点赞通知已被删除");
        }
        videoLikes.setIsDeleted(1);
        this.updateById(videoLikes);
        return Response.success("删除成功");
    }
}


